#include <Wire.h>
#include <SD.h>
#include "RTClib.h"
File archivo;
RTC_DS1307 RTC;

int analogicos[16];

char character;
String comando="";

int muestreo = 3000;
boolean guardandoSD=false;
String fecha="";
long ultimoEnvio = 0;
String separado[3];

void setup() {
  Serial.begin(9600);
  Wire.begin();
  RTC.begin();
  //RTC.adjust(DateTime(__DATE__, __TIME__));
  pinMode(53,OUTPUT);
  pinMode(10, OUTPUT);
  digitalWrite(10,HIGH);
  if (!SD.begin(4)){
    Serial.println("No se pudo inicializar la SD");
  }
  //initFiles();
  delay(100);
}

//void initFiles(){
//  if (!SD.exists("config.txt")) {
//    archivo = SD.open("config.txt", FILE_WRITE);
//    archivo.close();
//    if(SD.exists("config.txt"))
//      Serial.println("Se creo correctamente config.txt");
//    else
//      Serial.println("No se pudo crear config.txt");
//  }
//  else
//    Serial.println("Existe config.txt");
//    
//  if (!SD.exists("log.txt")) {
//    archivo = SD.open("log.txt", FILE_WRITE);
//    archivo.close();
//    if(SD.exists("log.txt"))
//      Serial.println("Se creo correctamente log.txt");
//    else
//      Serial.println("No se pudo crear log.txt");
//  }
//  else
//    Serial.println("Existe log.txt");
//}

void loop() {
  verificarComando();
  if( ( millis() - ultimoEnvio ) > muestreo ){
    ultimoEnvio =millis();
    String V="V:";
    for(int i=0;i<16;i++){
     if(analogicos[i]==1){
       V+="A"+i;
       String a = String (analogRead(i),DEC);
       V+=":"+a;
     }
    }
//    String a0 = String (analogRead(0),DEC);
//    V+= "A0:"+ a0;
//    String a1 = String (analogRead(1),DEC);
//    V+= "-A1:"+ a1;
//    String a2 = String (analogRead(2),DEC);
//    V+= "-A2:"+ a2;
    //String valores[] = {a0,a1,a2};
    Serial.println(V);
    //if(guardandoSD)
    //  guardarEnSD(valores,3); 
  }
}
//1=El micro guarda en SD la configuracion.
//2=El micro envia lo que hay en la SD.
//3=Procesa los pines digitales.
//4=Procesa los pines PWM.
//5=Lee lo que hay de salida.
//6=Actualiza los paramestro muestreo, fecha y hora y si guarda o no en SD.
//7=Lee los parametros muestreo, fecha y hora y si guarda o no en SD que tiene guardado el arduino.
void verificarComando(){
  while(Serial.available()) {
      character = Serial.read();
      comando.concat(character);
  }
  if (character == 10){
    Serial.println(comando.substring(0,1));
    switch(comando.substring(0,1).toInt()){
      case 0:testConnection();
      case 1:guardarConfiguracion();break;
      case 2:enviarConfiguracion();break;
      case 3:procesarDigital(comando.substring(1));break;
      case 4:procesarPWM(comando.substring(1));break;
      case 5:leerSalidas(comando.substring(2));break;
      case 6:actualizarParametros(comando.substring(2));break;
      case 7:leerParametros();break;
    }
    comando="";
    character='x';
  }
}

void guardarEnSD(String valores[], int length){
  String line = "";
  line+=getDate();
  for(int i=0;i<length; i++){
    line += ",";
    line += valores[i];
  }
  //line += String(",");
  File dataFile = SD.open("log.txt", FILE_WRITE);
  if (dataFile) {
    dataFile.println(line);
    dataFile.close();
  } 
  //Serial.println(line);
}

void leerSalidas(String comando){
  int total = countCharacter(comando,':')+1;
  split(comando,':');
  for(int i=0; i<total; i++){
    Serial.println(separado[i]);
    leerDigital(separado[i].substring(1).toInt());
  }
}

void leerDigital(int pin){
  int valor = digitalRead(pin);
  String salida = "S:D";
  salida = salida+pin+":" + valor;
  Serial.println(salida);
}

void procesarDigital(String comando){
  Serial.print("Procesando Digital..");
  Serial.println(comando);
  split(comando,':');
  digitalWrite(separado[0].toInt(),separado[1].toInt());
}

void procesarPWM(String comando){
  split(comando,':');
  analogWrite(separado[0].toInt(),separado[1].toInt());
}

void actualizarParametros(String comando){
  split(comando,'-');
  Serial.println("Actualizando parametros..");
  //Serial.print(separado[0]);Serial.print(", ");Serial.print(separado[1]);Serial.print(", ");Serial.println(separado[2]);
  muestreo = separado[0].toInt();
  if(separado[1].toInt()==1)
    guardandoSD=true;
  else
    guardandoSD=false;
  fecha = String(separado[2]); 
  delay(10);
}

void leerParametros(){
  String parametros = "P:";
  parametros += String(muestreo);
  parametros += String("-");
  parametros += String(guardandoSD);
  parametros += String("-");
  parametros += fecha;
  Serial.println(parametros);
}

void guardarConfiguracion(){
  String linea="";
  SD.remove("config.txt");
  delay(10);
  archivo = SD.open("config.txt", FILE_WRITE);
  if(archivo){
    Serial.println("Guardando Configuracion..");
    while(!linea.startsWith("EOF")){
      while(Serial.available()) {
          character = Serial.read();
          linea.concat(character);
      }
      if (character == 10){
        archivo.println(linea);
        linea="";
        character='x';
      }
    }
    archivo.close();
  }
  else
    Serial.println("Error al abrir el archivo");
  Serial.println("Termina guardarConfiguracion()");
}

void enviarConfiguracion(){
 archivo = SD.open("config.txt");
  if (archivo) { 
    Serial.println("CONFIGURACIONSD");
    while (archivo.available()) {
      char caracter = archivo.read();
      Serial.write(caracter);
      if(caracter ==10)
        delay(200);
    }
    archivo.close();
    Serial.println("EOFSD");
  } else {
    Serial.println("EOFSD");
    Serial.println("error opening config.txt");
  }
  Serial.println("Fin.");
}

void split(String line, char character){
  const char * s = &character;
  line+=" ";
  char sz[line.length()];
  line.toCharArray(sz,line.length());
  char *p = sz;
  char *str;
  int count=0;
  while ((str = strtok_r(p, s, &p)) != NULL){
    String c =str;
    //Serial.println(str);
    separado[count] = c;
    count++;
  }
}

int countCharacter(String line,char character){
  int counter = 0;
  for( int i=0; i<line.length(); i++ ) {
    if( line.charAt(i) == character ) {
      counter++;
    } 
  }
  return counter;
}

void testConnection(){
 Serial.println("OK");
}

String getDate(){
  String date = "";
  DateTime now = RTC.now();
  delay(10);
  date += String(now.year(), DEC);
  date += String('/');
  date += String(now.month(), DEC);
  date += String('/');
  date += String(now.day(), DEC);
  date += String(' ');
  date += String(now.hour(), DEC);
  date += String(':');
  date += String(now.minute(), DEC);
  date += String(':');
  date += String(now.second(), DEC);
  return date;
}

void cargarConfiguracion(){
  for(int i=0;i<16;i++){
     String porp = getPropiedad("A"+i);
     analogicos[i]=1;
     analogicos[i]=0;
  }
}

String getPropiedad(String propiedad){
  archivo = SD.open("config.txt");
  String linea = "";
  if (archivo) { 
    while (archivo.available()) {
      char caracter = archivo.read();
      linea.concat(character);
      if (character == 10){
        //archivo.println(linea);
        if(getNombrePropiedad().equals(propiedad))
          return getValorPropiedad(propiedad);
        linea="";
        character='x';
      }
    }
    archivo.close();
  } else {
    Serial.println("Error al abrir el archivo");
  }
  return "";
}

String getNombrePropiedad(String linea){
  int i = linea.indexOf('=');
  String sub = linea.substring(0,i);
  Serial.println(sub);
  return sub;
}

String getValorPropiedad(String linea){
  int i = linea.indexOf('=');
  String sub = linea.substring(i+1,linea.length());
  Serial.println(sub);
  return sub;
}
